구현내용

  • fetch API를 통해 api를 받아와서 JSON형태로 가공
  • JSON데이터를 input에 입력 할때 데이터만 필터링
  • 필터링된 문자 하이라이트 표시

🏷 fetch API

웹피이지 전체를 리로드하지 않고 일부분만을 리로드하고 비동기싱으로 데이터를 불러와 작업하는 XMLHttpRequest 객체

web에서 비동기로 요청하기 위해서는 XHR객체사용
IE에서 ajax 요청을 보내기가 까다로워서 jquery AJAXaxios, superagent같은 라이브러리 등장

XHR의 부족한 부분을 보완하기 위해서 Fetch API를 도입

axios는 XHR을 사용하는데, Service Worker등의 최신 기숭이 XHR을 지원하지 않으므로 Service worker를 사용할 예정이라면 Fetch API를 사용해야 합니다.
create-react-app 에도 Service Worker가 있습니다.

1
2
3
4
// fetch api
fetch(endpoint)
.then(blob => blob.json())
.then(data => cities.push(...data));

code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
//endpoint변수에 주소를 담음
const endpoint =
"https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json";

// cities 초기화, 검색어에 따라서 변환
const cities = [];

// fetch api
fetch(endpoint)
// 객체의 값을 json으로 변환
.then(blob => blob.json())
// data에 'cities에 ...data'를 push
.then(data => cities.push(...data));

// 기본구조: fetch('주소', 설정객체).then(콜백).catch(콜백);

function findMatches(wordToMatch, cities) {
//wordToMatch : input text value
// 여기서 우리는 도시나 제대로 검색된 것과 일치하는지 알아내야함
return cities.filter(place => {
// RegExp : 사용하면 문자열을 검색하고 문자열의 텍스트를 바꾸는 데 사용할 수 있는 패턴인 일반 표현식을 사용할 수 있습니다
const regex = new RegExp(wordToMatch, "gi");
// RegExp match매소드 : 대응되는 문자열을 찾는 RegExp 메소드입니다. 정보를 가지고 있는 배열을 반환합니다. 대응되는 문자열을 찾지 못했다면 null을 반환합니다.
return place.city.match(regex) || place.state.match(regex);
});
}

// toString() : 숫자를 문자형으로 변환
// replace() : 문자열의 특정 부분을 바꾼 새 문자열을 생성할때 사용
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

function displayMatches() {
//일치하는 값을 matchArray에 담기
const matchArray = findMatches(this.value, cities);
//this = target.event
const html = matchArray
.map(place => {
const regex = new RegExp(this.value, "gi");
const cityName = place.city.replace(
regex,
`<span class="hl">${this.value}</span>`
);
const stateName = place.state.replace(
regex,
`<span class="hl">${this.value}</span>`
);
return `
<li>
<span class="name">${cityName}, ${stateName}</span>
<span class="population">${numberWithCommas(place.population)}</span>
</li>
`;
})
.join("");
suggestions.innerHTML = html;
}

const searchInput = document.querySelector(".search");
const suggestions = document.querySelector(".suggestions");

searchInput.addEventListener("change", displayMatches);
searchInput.addEventListener("keyup", displayMatches);